/*
 * C/C++ Lessons Program
 * 
 * Copyright (c) 2012 Ken Zhang (cpp.china@hotmail.com)
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this program; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA  02111-1307  USA
 *
 */


#include <string.h>
#include <stdio.h>

char *strreplace(char *dest, size_t size, const char *src, const char *tofind, const char *replacement)
{
	int len1 = strlen(tofind);
	int len2 = strlen(replacement);
	char *ret = dest;
	const char *p = NULL;
	int available = size, n = 0;
	
	switch (size) {
	case 0: // Return NULL if no space
		return NULL;
	case 1: // Return empty string if size is 1
		dest[0] = '\0';
		return ret;
	default:
		memset(dest, 0, size);
	}
	
	do {
		// calculate available space, not including the space for terminated char '\0'.
		available = size - (dest - ret) - 1;
		
		// find string to replace
		p = strstr(src, tofind);
		
		if (p != NULL) {
			// when a target string is found, copy the part left to the target
			if (available > p - src) {
				strncpy(dest, src, p - src);
			}
			else {
				strncpy(dest, src, available);
				dest[available] = '\0';
				break;
			}
			
			available -= (p - src);
			
			// then copy the replacement
			if (available > len2) {
				strcat(dest, replacement);
				dest += (p - src) + len2;
				src = p + len1;
			}
			else {
				strncat(dest, replacement, available);
				dest[available] = '\0';
				break;
			}
		}
		else {
			// no more target string found, copy the rest of source stirng
			if (available > strlen(src)) {
				strcat(dest, src);
			}
			else {
				strncat(dest, src, available);
				dest[available] = '\0';
				break;
			}
		}
	} while (p != NULL && available > 0);
	
	return ret;
}

int main()
{
	const char *hello = " Hello Worlld ";
	char buffer[128];
	printf("Replace '%s' -> '%s'\n", hello, strreplace(buffer, 10, hello, "ll", "XXX"));
	return 0;
}

